/*!
 * \file DataStruct.h
 * \date 2021/01/24 10:57
 *
 * \author wanyzh
 * Contact: yizhao_wan@126.com
 *
 * \brief Header file of the CMesh class for the geometry and finite element mesh.
 *
 * TODO: long description
 *
 * \note
*/
#pragma once
#include "point.h"
#include "Element.h"
/*!
 * \class CMesh
 *
 * \brief Mesh class which contains the P,Pb,T,Tb and boundary nodes and edges
 *
 * \author wanyzh
 * \date Jan 2021
 */
class CMesh
{
public:
	///@brief Get P 
	//return value is a vector, and the [] operator of vector is not constant
	//so the return value should not be a constant
	vector<CPoint>&getPoints();

	///get T
	vector<CElement> &getElements();

	///get Pb_test
	vector<CPoint> &getPbTest();

	///get Tb_test
	vector<CElement> &getTbTest();

	///get Pb_trial
	vector<CPoint> &getPbTrial();

	///get Tb_trial
	vector<CElement> &getTbTrial();

	///read mesh from file 
	///fill the m_Points and m_Elements
	bool readMeshFromFile(string filename);

	//get all the boundary nodes
	vector<vector<boundary_node>> &getAllBoundNodes();

	///get all the boundary edges
	vector<vector<boundary_edge>> &getAllBoundEdges();

	///assign one boundary nodes value
	void assignBoundNodesValue(vector<boundary_node> &bound,int num_vec,BOUNDARY_TYPE type, double(*value)(CPoint,double t));

	///assign one boundary edges value
	void assignBoundEdgesValue(vector<boundary_edge> &bound, int num_vec,BOUNDARY_TYPE type, double(*value)(CPoint,double t),double(*r)(CPoint,double t));

	///generate P and T from Pb and Tb
	void generatePT();

	///Get the index of the element K in the vector T
	template<class T>
	int getVectorIndex(vector<T> &,T K);

	///export P and T or Pb and Tb to vtk file
	void exportPT2Vtk(string filename, vector<CPoint> &P,  vector<CElement> &T);


private:
	///Pb_test read from mesh file
	vector<CPoint> m_Points;

	///Tb_test
	vector<CElement> m_Elements;

	///Pb_trial
	vector<CPoint> m_PbTrial;

	///Tb_trial
	vector<CElement> m_TbTrial;

	vector<CPoint> m_P;

	///Tb_trial
	vector<CElement> m_T;	

	///boundary_nodes recorded with each boundary
	vector<vector<boundary_node>> m_allBoundaryNodes;

	///boundary edges recorded with each boundary
	vector<vector<boundary_edge>> m_allBoundaryEdges;
};

